package com.threadmethod.wait;

import java.util.ArrayList;
import java.util.List;
import sun.plugin.javascript.navig.Array;

/**
 * @PackageName:com.threadmethod.wait
 * @ClassName:Test09
 * @Description: wait条件产生变化
 *  定义一个集合 定义一个线程向集合中添加数据，添加完数据后通知另外的线程从集合中取数据
 *  定义一个线程从集合中取数据，如果集合中没有数据就等待
 * @Author: zhangxiaoyu
 * @date 2021/1/11 17:37
 */
public class Test09 {
    
    public static void main(String[] args){

        //定义添加数据的线程对象
        ThreadAdd threadAdd = new ThreadAdd();
        //定义取数据的线程对象
        ThreadSubtract threadSubtract = new ThreadSubtract();
        threadSubtract.setName("substract 1");

        //测试一：先开启添加数据的线程，再开启一个取数据的线程，大多数的情况下会正常取数据
       /* threadAdd.start();
        threadSubtract.start();*/

       //测试二：先开启取数据的线程，再开启添加数据的线程,取数据的线程会先等待，等到添加数据之后，再取数据
     /*   threadSubtract.start();
        threadAdd.start();*/

      //测试三：开启两个取数据的线程，再开启添加数据的线程
        ThreadSubtract threadSubtract2 = new ThreadSubtract();
        threadSubtract2.setName("substract 2");
        threadSubtract.start();
        threadSubtract2.start();
        threadAdd.start();

    }

    //定义一个list集合
    static List list = new ArrayList();

    //定义方法从集合中取数据
    public  static void  subtract(){
        
        synchronized (list){
            //if(list.size()==0){
            while (list.size()==0){
                try {
                    System.out.println(Thread.currentThread().getName()+"begin -------");
                    list.wait();
                    System.out.println(Thread.currentThread().getName()+"end-------");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
            Object data = list.remove(0);
            
            System.out.println(Thread.currentThread().getName()+"从集合中取了"+data+"后，集合中的数量："+list.size());
        }
        
    }

    //定义方法向集合中添加数据 然后通知等待的线程取数据
    public  static void  add(){

        synchronized (list){
            list.add("data");
            list.notifyAll();
        }
    }

    //定义一个线程类调用方法取数据
    static  class ThreadAdd extends Thread{
        @Override
        public void run() {
            add();
        }
    }

    //定义线程类调用subtract
    static  class ThreadSubtract extends Thread{
        @Override
        public void run() {
            subtract();
        }
    }

}
